// strc_ref.cpp -- using structure references
#include <iostream>
#include <string>

// 定义一个结构体 free_throws，用于存储球员的罚球信息
struct free_throws
{
    std::string name;    // 球员姓名
    int made;            // 成功罚球次数
    int attempts;        // 罚球总次数
    float percent;       // 罚球成功率
};

// 函数声明
void display(const free_throws & ft);                      // 显示罚球信息
void set_pc(free_throws & ft);                             // 计算罚球成功率并设置
free_throws & accumulate(free_throws &target, const free_throws &source);  // 累加罚球信息

int main()
{
    // 创建五个球员的罚球记录
    free_throws one = {"Ifelsa Branch", 13, 14};
    free_throws two = {"Andor Knott", 10, 16};
    free_throws three = {"Minnie Max", 7, 9};
    free_throws four = {"Whily Looper", 5, 9};
    free_throws five = {"Long Long", 6, 14};
    free_throws team = {"Throwgoods", 0, 0}; // 团队的总记录
    free_throws dup; // 用于存储累计结果的副本

    // 设置第一个球员的罚球成功率并显示信息
    set_pc(one);
    display(one);

    // 累加第一个球员的罚球记录到团队记录
    accumulate(team, one); // Made: 13 Attempts: 14 Percent: 92.8571
    display(team); // 显示团队记录

    // 使用返回值作为参数调用显示函数
    display(accumulate(team, two)); // 将第二个球员记录累加到团队并显示
    accumulate(accumulate(team, three), four); // 累加第三和第四个球员的记录到团队
    display(team); // 显示更新后的团队记录

    // 使用返回值进行赋值
    dup = accumulate(team, five); // 将团队的新记录赋值给 dup
    std::cout << "Displaying team:\n";
    display(team); // 显示团队记录
    std::cout << "Displaying dup after assignment:\n";
    display(dup); // 显示 dup 记录

    // 更新第四个球员的罚球成功率
    set_pc(four);

    // 不推荐的赋值操作，演示引用的使用
    accumulate(dup, five) = four; // 将第四个球员的记录赋值给 dup 累加的结果
    std::cout << "Displaying dup after ill-advised assignment:\n";
    display(dup); // 显示 dup 记录

    // std::cin.get(); // 取消注释可用于暂停程序等待用户输入
    return 0; // 程序结束
}

// 显示罚球信息的函数，使用常量引用以保证不修改原始数据
void display(const free_throws & ft)
{
    using std::cout; // 使用 std::cout
    cout << "Name: " << ft.name << '\n'; // 显示球员姓名
    cout << "  Made: " << ft.made << '\t'; // 显示成功罚球次数
    cout << "Attempts: " << ft.attempts << '\t'; // 显示罚球总次数
    cout << "Percent: " << ft.percent << '\n'; // 显示罚球成功率
}

// 计算并设置罚球成功率的函数
void set_pc(free_throws & ft)
{
    // 使用成功次数和总次数计算成功率
    if (ft.attempts != 0)
        ft.percent = 100.0f * float(ft.made) / float(ft.attempts); // 计算成功率
    else
        ft.percent = 0; // 如果没有罚球尝试，则成功率为 0
}

// 累加一个球员的罚球记录到目标记录的函数
free_throws & accumulate(free_throws & target, const free_throws & source)
{
    target.attempts += source.attempts; // 累加总尝试次数
    target.made += source.made; // 累加成功次数
    set_pc(target); // 更新成功率
    return target; // 返回目标记录的引用
}
